package com.shanlitech.bluetooth.sample;

import android.content.Context;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.shanlitech.lbs.geometry.Point2D;
import com.shanlitech.lbs.map.MapFlat;
import com.shanlitech.lbs.types.AccelerationRecord;
import com.shanlitech.lbs.types.RssiRecord;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;

import com.shanlitech.lbs.sample.*;

public class SampleRecorder {
    private final Context context;
    private final LinkedList<RssiRecord>    rssiRecords = new LinkedList<>();
    private final LinkedList<AccelerationRecord>  accRecords = new LinkedList<>();

    public SampleRecorder(Context context) {
        this.context = context;
    }

    public void clear() {
        rssiRecords.clear();
    }

    public void addRssi(RssiRecord r) {
        rssiRecords.add(r);
    }

    public void addRssi(Collection<RssiRecord> r) {
        rssiRecords.addAll(r);
    }

    public void addAcc(AccelerationRecord r) {
        accRecords.add(r);
    }

    public void addAcc(Collection<AccelerationRecord> r) {
        accRecords.addAll(r);
    }

    public boolean isEmpty() {
        return rssiRecords.isEmpty();
    }

    public OneshotSample saveAsOneshot(MapFlat flat, Point2D location) {
        if( rssiRecords.isEmpty() ) {
            return null;
        }
        final Date date = Calendar.getInstance().getTime();
        final OneshotSample sample = new OneshotSample(flat.getPartition(),flat.getFloor(),date,location,rssiRecords,accRecords);

        save(context,sample);
        clear();
        SampleDatabase.getInstance(context).addOneshot(sample);
        return sample;
    }

    public RealtimeSample saveAsRealtime(MapFlat flat) {
        if( rssiRecords.isEmpty() ) {
            return null;
        }
        final Date date = Calendar.getInstance().getTime();
        final RealtimeSample sample = new RealtimeSample(flat.getPartition(),flat.getFloor(), date,rssiRecords,accRecords);

        save(context,sample);

        clear();
        SampleDatabase.getInstance(context).addRealtime(sample);
        return sample;
    }

    public CalibrationSample saveAsCalibration(MapFlat flat,Point2D location) {
        if( rssiRecords.isEmpty() ) {
            return null;
        }
        final Date date = Calendar.getInstance().getTime();
        final CalibrationSample sample = new CalibrationSample(flat.getPartition(),flat.getFloor(), date,location,rssiRecords);
        save(context,sample);

        clear();
        SampleDatabase.getInstance(context).addCalibration(sample);
        return sample;
    }

    public static void save(Context context,OneshotSample sample) {
        final File dir = requireDir(context,"oneshot");
        if( dir == null ) {
            return;
        }
        final JSONObject json = sample.toJsonObject();
        final String content = json.toString(SerializerFeature.PrettyFormat);

        final File file = new File(dir,sample.getFileName());
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    public static void save(Context context,RealtimeSample sample) {
        final File dir = requireDir(context,"realtime");
        if( dir == null ) {
            return;
        }
        final JSONObject json = sample.toJsonObject();
        final String content = json.toString(SerializerFeature.PrettyFormat);

        final File file = new File(dir,sample.getFileName());
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void save(Context context,CalibrationSample sample) {
        final File dir = requireDir(context,"calibration");
        if( dir == null ) {
            return;
        }
        final JSONObject json = sample.toJsonObject();
        final String content = json.toString(SerializerFeature.PrettyFormat);

        final File file = new File(dir,sample.getFileName());
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(file))) {
            writer.write(content);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private static File requireDir(Context context,String sub) {
        File dir = new File(context.getFilesDir(),sub);
        if( !dir.exists() ) {
            if( dir.mkdir() ) {
                return dir;
            }
        } else if( dir.isDirectory() ) {
            return dir;
        }
        return null;
    }
}
